﻿////////////////////////////////////////////////////////////////////////////////
//  VICMAN
//  Copyright 2010 Vicman
//  All Rights Reserved.
//
//  Created on:      08-Jun-2010 11:47:45
//  Original author: Alexey Kolonitsky
////////////////////////////////////////////////////////////////////////////////

package org.kolonitsky.alexey.net
{
    import flash.events.ErrorEvent;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.HTTPStatusEvent;
    import flash.events.IOErrorEvent;
    import flash.events.SecurityErrorEvent;
    import flash.events.TextEvent;
    import flash.net.URLLoader;
    import flash.net.URLLoaderDataFormat;
    import flash.net.URLRequest;
    import flash.utils.ByteArray;

    import org.kolonitsky.alexey.events.MessageEvent;

    /**
     *
     */
    [Event(name="complete", type="flash.events.Event")]

    /**
     *
     */
    [Event(name="error", type="org.kolonitsky.alexey.events.MessageEvent")]


    /**
     *  Loading XML file.
     *
     *  @author Alexey Kolonitsky
     *  @date 25.05.2009
     */
    public class XMLService extends EventDispatcher
    {
        /**
         *  XML Root tag. This parameter allow cut only xml content from
         *  loaed file
         */
        public var rootCloseNode:String = "";

        /**
         *  Base url for request started witout `http://` or `/`
         */
        public var baseURL:String = "/";

        /**
         *  Constructor
         */
        public function XMLService(uri:String=""):void
        {
            this.uri = new URLRequest();
            this.uri.url = uri
        }

        /**
         *  Load xml
         *  After loading content availabel in lastData field.
         *
         *  @param uri can be String or URLRequest.
         *
         *  @pra
         */
        public function load (uri:*, format:String=URLLoaderDataFormat.TEXT):void 
        {
            if (uri is String)
                this.uri.url = uri;

            if (uri is URLRequest)
                this.uri = uri as URLRequest;

            if (this.uri.url.search(new RegExp("^(/|https?://)")) == -1)
                this.uri.url = baseURL + this.uri.url;

            loader = new URLLoader();
            loader.dataFormat = format;
            loader.addEventListener(Event.COMPLETE, loader_completeHandler);
            loader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
            loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSequrityError);
            loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, loader_httpStatusHandler);
            loader.load(this.uri);
        }

        /**
         *  Last successful loaded data
         */
        public function get lastData ():XML
        {
            return _data;
        }




        //----------------------------------------------------------------------
        //
        // Override
        //
        //----------------------------------------------------------------------

        /**
         *
         */
        protected var _data:XML;

        /**
         *
         */
        protected var rawData:*;

        /**
         * Work uri of service
         */
        protected var uri:URLRequest;

        /**
         * Pars loaded XML immediatly after load.
         */
        protected function pars():void { }

        /**
         *
         */
        protected function errorHandler(message:String):void
        {
            trace("ERROR: XMLService. " + message);
            dispatchEvent(new MessageEvent(MessageEvent.ERROR, true, false, message))
        }




        //----------------------------------------------------------------------
        //
        // Private logic
        //
        //----------------------------------------------------------------------

        /**
         * URLLoader for loading
         */
        private var loader:URLLoader;

        /**
         * Cut only content xml
         **/
        private function loader_completeHandler (event:Event): void
        {
            rawData = event.target.data;

            if (event.target.data is String)
            {
                var str:String = String(event.target.data);
                if (rootCloseNode != "")
                {
                    var ind: int = str.indexOf(rootCloseNode);
                    ind += rootCloseNode.length;
                    _data = XML(str.substring(0, ind));
                }
                else
                {
                    try
                    {
                        _data = XML(str);
                    }
                    catch (error:Error)
                    {
                        errorHandler(error.message);
                    }
                }
            }
            pars();

            event.stopPropagation();
            dispatchEvent(new Event(Event.COMPLETE, false, false));
        }

        private function onIOError(event:IOErrorEvent):void
        {
            errorHandler(event.text)
            event.stopImmediatePropagation();
        }

        private function onSequrityError(event:SecurityErrorEvent):void
        {
            errorHandler(event.text)
            event.stopImmediatePropagation();
        }

        private function loader_httpStatusHandler(event:HTTPStatusEvent):void
        {
        }
   }
}